package com.shenmazong.servershopgateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shenmazong.comm.pojo.TokenInfo;
import com.shenmazong.comm.utils.JwtUtil;
import com.shenmazong.comm.utils.ResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Configuration
@Slf4j
public class GateWayFilterConfig implements GlobalFilter, Ordered {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private String makeResult(Integer code, String message) {
        ResultResponse result = ResultResponse.FAILED(code, message);

        ObjectMapper mapper = new ObjectMapper();
        String msg = "{'code':-1, 'message':'未知错误'}";

        try {
            msg = mapper.writeValueAsString(result);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return msg;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //--1 获取请求和相应对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        log.info("gateway.......");


        //--2 获取头部中的token
        String token = request.getHeaders().getFirst("token");
        if(token == null) {

            String msg = makeResult(-1, "没有登录");

            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }

        //-- 解析token
        TokenInfo info = JwtUtil.getTokenByString(token);
        if(info == null) {
            String msg = makeResult(-1, "没有登录");

            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }

        //-- 根据用户ID获取作为key的token
        String keyToken = stringRedisTemplate.opsForValue().get(info.getUserId().toString());
        if(keyToken == null) {
            String msg = makeResult(-1, "没有登录");

            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }
        if(!keyToken.equals(token)) {
            // 这时候别人已经登录了
            String msg = makeResult(-1, "该账号已经异地登录了");

            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }

        //-- keyToken
        String newToken = stringRedisTemplate.opsForValue().get(keyToken);
        if(newToken == null){
            String msg = makeResult(-1, "没有登录");

            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }

        //-- 解析newToken
        boolean ok = JwtUtil.verifyToken(newToken);
        if(!ok) {
            String msg = makeResult(-1, "没有登录");

            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }

        //-- 产生新的token

        //-- 把新的token存入到redis

        ///-- 放行


//        boolean verifyToken = JwtUtil.verifyToken(token);
//        if(!verifyToken) {
//            String msg = makeResult(-1, "token错误");
//
//            DataBuffer dataBuffer = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
//            return response.writeWith(Mono.just(dataBuffer));
//        }

        //-- token自动刷新
        // 1、生产token的时候放到redis
        // 2、tokenvalue=key,newtoken=value

        //-- 不允许多端登录的问题解决
        // userid=key,token=value
        // token -> newtoken

        // 放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
